#ifndef F1C488C7_A424_4839_A8A0_C64530D6924E
#define F1C488C7_A424_4839_A8A0_C64530D6924E

#include "equation.hpp"
#include "method.hpp"
#include <iostream>

const unsigned long long max_it = 1000000;
static double newton_function(Equation const &eq, double eps, double x0) {
  unsigned long long it = 0;
  while (it++ < max_it) {
    if (double dx = eq.get_first_derivative()(x0); std::abs(dx) <= eps) {
      return x0;
    }
    x0 -= eq.get_first_derivative()(x0) / eq.get_second_derivative()(x0);
  }
  return x0;
}

class NewtonMethod
    : public Method<std::function<double(Equation const &, double, double)>> {
private:
  double x0;

public:
  explicit NewtonMethod(double x0)
      : Method(newton_function, "Метод Ньютона"), x0(x0){};

  double solve(Equation const &eq, double _a, double _b,
               double eps) const override {
    return this->get_solver()(eq, eps, x0);
  }
};

#endif /* F1C488C7_A424_4839_A8A0_C64530D6924E */
